from concurrent.futures import ProcessPoolExecutor
import math
import os
import cv2
from werkzeug.utils import secure_filename
from datetime import datetime
import hashlib
import shutil
from moviepy.video.io.VideoFileClip import VideoFileClip
import uuid
from PIL import Image
import numpy as np
import imagehash
from dataclasses import asdict

from file_utils import fast_json_read, find_files, get_partial_md5, safe_json_write
from video_utils import VideoFile, get_video_info, is_video_hash_close

PERSIST_DB_NAME = "visit.db"
MAX_WORKER = 4


def get_duplicate_video_file(video_path):
    files = find_files(video_path)
    visited_files = fast_json_read(PERSIST_DB_NAME)

    count = 1
    video_files = []
    # for i in files:
    #     print(f"文件解析中，当前处理第{count}/{len(files)}个")
    #     key = os.path.basename(i) + get_partial_md5(i)
    #     count += 1
    #     get_video_obj(visited_files, i)

    with ProcessPoolExecutor(max_workers=MAX_WORKER or os.cpu_count()) as executor:
        futures = [executor.submit(get_video_obj, visited_files, fpath, idx, len(files)) for idx, fpath in enumerate(files)]
        for future in futures:
            result = future.result()
            if result is not None:
                key, item = result
                video_files.append(item)
                visited_files[key] = asdict(item)

    hash_map = {}
    visited_path = set()
    count = 1
    for i in video_files:
        print(f"重复文件识别中，当前处理第{count}/{len(video_files)}个")
        count += 1
        if i.path in visited_path:
            continue
        visited_path.add(i.path)
        cur_list = [i]
        for j in video_files:
            if j.path in visited_path or (j.path == i.path):
                continue
            if is_video_hash_close(i.hash, j.hash) and math.isclose(i.duration, j.duration, rel_tol=1e-9, abs_tol=0.0):
                cur_list.append(j)
                visited_path.add(j.path)
        if len(cur_list) > 1:
            hash_map[i.path] = cur_list

    safe_json_write(visited_files, PERSIST_DB_NAME)

    return hash_map

# def get_video_obj(visited_files, video_files, i, key):
#     if key in visited_files:
#         video_files.append(VideoFile(**visited_files.get(key)))
#     else:
#         item = get_video_info(i)
#         video_files.append(item)
#         visited_files[key] = asdict(item)

def get_video_obj(visited_files, i, idx, total):
    print(f"文件解析中, 第{idx}个，总共{total}个")
    key = os.path.basename(i) + get_partial_md5(i)
    if key in visited_files:
        return key, VideoFile(**visited_files.get(key))
    else:
        return key, get_video_info(i)

if __name__ == '__main__':
    target_path = r'E:\test'
    tmp_remove_path = os.path.join(target_path, "file_to_remove")
    os.makedirs(tmp_remove_path, exist_ok=True)
    get_duplicate_video_file(target_path)
    pass

    